package haoji_juc;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @program: Dome
 * @description: Callable
 * @className: TestCallable
 * @author: rjt99999
 * @version: 1.0.0
 * @create: 2020-08-03 18:32
 **/
public class TestCallable {

    /*般使用线程池执行任务都是调用的execute方法，这个方法定义在Executor接口中
    oid execute(Runnable command);这个方法是没有返回值的，而且只接受Runnable。

    ExecutorService接口中
    <T> Future<T> submit(Callable<T> task);


    <T> Future<T> submit(Runnable task, T result);虽然submit传入Runnable不能直接返回内容，但是可以通过submit(Runnable task, T result)传入一个载体，通过这个载体获取返回值。
    这个其实不能算返回值了，是交给线程处理一下。
     Future<?> submit(Runnable task);因为Runnable是没有返回值的，所以如果submit一个Runnable的话，get得到的为null


    区别：

1.Callable能接受一个泛型，然后在call方法中返回一个这个类型的值。而Runnable的run方法没有返回值
2.Callable的call方法可以抛出异常，而Runnable的run方法不会抛出异常。
     */

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ExecutorService executorService = Executors.newFixedThreadPool(2);


        Future<String> future = executorService.submit(() -> {

                Thread.sleep(3000);
            System.out.println("call()方法执行了。。。");
            return "hahha";

        });


        System.out.println("获取返回值之前" + TestCallable.getStringDate());

        //get()获取返回的值，方法的阻塞性 -任务还没有执行完，所以会一直等到任务完成，形成了阻塞。反之则无
        //submit两个任务时，总阻塞时间是最长的那个

        /**get(long var1, TimeUnit var3--超时时间)
         前面都是用的get()方法获取返回值，那么因为这个方法是阻塞的，有时需要等很久。所以有时候需要设置超时时间

         *方法的第一个参数是长整形数字，第二个参数是单位，跟线程池ThreadPoolExecutor的构造方法里一样的。
         */

        String s = future.get();//3秒后拿到值
        System.out.println("s = " + s);

        System.out.println("获取返回值之后" + TestCallable.getStringDate());


    }

    public static String getStringDate() {


        Date currentTime = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");

        return simpleDateFormat.format(currentTime);
    }


}
